package main

import (
	"app/api"
	"app/pb"
	"flag"
	"fmt"
	"github.com/grpc-ecosystem/go-grpc-middleware"
	"github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus"
	"github.com/grpc-ecosystem/go-grpc-middleware/recovery"
	"github.com/grpc-ecosystem/go-grpc-middleware/tags"
	"github.com/sirupsen/logrus"
	"google.golang.org/grpc"
	"net"
	"os"
	ugrpc "app/grpc"
)

var (
	webPort int
	grpcPort int
	startWeb bool
	startGrpc bool
)



func init()  {
	flag.IntVar(&webPort,"wp",10000,"web port for http server")
	flag.IntVar(&grpcPort,"gp",10001,"grpc port for grpc server")
	flag.BoolVar(&startWeb,"w",false,"start http server")
	flag.BoolVar(&startGrpc,"g",false,"start grpc server")


	flag.Parse()
}


func main()  {

	if !startWeb && !startGrpc {
		fmt.Println("usage: ./server -[wp|gp] port -[w|g]")
		os.Exit(0)
	}

	logger := logrus.New()
	var err error

	if startWeb {
		err = newWebserver(logger)
	} else {
		err = newGrpcServer(logger)
	}
	if err != nil {
		logger.Fatal(err)
	}
}

func newWebserver(logger *logrus.Logger) error {
	srv , err := api.NewServer(logger,webPort,grpcPort)
	if err != nil {
		return err
	}
	return srv.Start()
}


func newGrpcServer(logger *logrus.Logger) (error) {
	var opts []grpc.ServerOption

	// Recovery middleware
	recoveryFn := func(err interface{}) error {
		logger.Errorln("Panic:", err)
		return nil
	}
	recoveryOpt := grpc_recovery.WithRecoveryHandler(recoveryFn)

	opts = append(opts,
		// stream interceptor
		grpc_middleware.WithStreamServerChain(
			grpc_ctxtags.StreamServerInterceptor(),
			grpc_logrus.StreamServerInterceptor(logrus.NewEntry(logger)),
			grpc_recovery.StreamServerInterceptor(recoveryOpt)),

		// unary interceptor
		grpc_middleware.WithUnaryServerChain(
			grpc_ctxtags.UnaryServerInterceptor(),
			grpc_logrus.UnaryServerInterceptor(logrus.NewEntry(logger)),
			grpc_recovery.UnaryServerInterceptor(recoveryOpt)),
	)


	userSve := ugrpc.NewUserService()


	// register gRPC service
	gRPCServer := grpc.NewServer(opts...)

	pb.RegisterUserServiceServer(gRPCServer,userSve)

	l,err := net.Listen("tcp",fmt.Sprintf(":%d",grpcPort))

	if err != nil {
		return err
	}

	return gRPCServer.Serve(l)
}